package process

import (
	"chat-cli/message"
	"chat-cli/utils"
	"encoding/json"
	"fmt"
	"net"
)

//ooa 关联用户相关操作的对象
type UserProcess struct {
}

// 这里的文件在编译时因为只编译了main 包下 的main 可能会导致 未定义
//使用 go run . 可以解决
//完成登录校验
func (up *UserProcess) Login(userId int, userPwd string) (err error) { //这里利用error返回信息量更大

	//开始定义协议

	//1 连接到服务器
	conn, err := net.Dial("tcp", "localhost:8889")
	if err != nil {
		fmt.Println("net.Dial err = ", err)
		return
	}
	defer conn.Close()

	//2 准备通过conn 发送消息给服务
	var mes message.Message
	mes.Type = message.LoginMesType
	//3 创建一个LoginMes 结构体
	var loginMes message.LoginMes
	loginMes.UserId = userId
	loginMes.UserPwd = userPwd

	//序列化的本质就是转为json格式  其本身是string

	//4.将loginMes 序列化  这里data的类型是byte切片

	data, err := json.Marshal(loginMes)
	if err != nil {
		fmt.Println("json.Marshal1 err=", err)
		return
	}
	//5 把登录信息赋给了 mes.data 字段
	mes.Data = string(data)
	//6 把mes  最终消息 进行序列化  即使要发送的数据
	data, err = json.Marshal(mes)
	if err != nil {
		fmt.Println("json.Marshal2 err=", err)
		return
	}
	tf := &utils.Transfer{
		Conn: conn,
	}
	err = tf.WritePkg(data)
	if err != nil {
		fmt.Println("发送数据异常！！", err)
		return
	}

	// //7 准备发送消息给服务器
	// /* 注意这里采用的纠错方案是先将数据的长度发送给服务端  然后在发送具体的数据包
	// 但是在网络环境下  消息到达的顺序是不一定的 所以尽量将消息的长度直接 存放到结构体中去
	// */
	// //7.1 先把data 的长度发送给服务器
	// //先获取data 的长度  将其转成一个表示长度的byte切片
	// pkgLen := uint32(len(data))
	// var bytes [4]byte
	// //这里使用了binary包下的方法 将uint长度值转换为字节数组
	// binary.BigEndian.PutUint32(bytes[0:4], pkgLen)
	// //发送长度
	// n, err := conn.Write(bytes[0:4])
	// if n != 4 || err != nil {
	// 	fmt.Println("conn.write len err = ", err)
	// 	return
	// }

	// fmt.Println("客户端发送消息长度成功!")

	// n, err = conn.Write(data)
	// if err != nil || n != int(pkgLen) {
	// 	fmt.Println("conn.write data err = ", err)
	// 	return
	// }

	//这里还需要处理服务器端返回的消息
	mes, err = tf.ReadPkg()
	//将接受的结果尽心反序列化以了解其登录的结果
	if err != nil {
		fmt.Println("返回消息接受异常:", err)
		return
	}
	var loginResMes message.LoginResMes
	err = json.Unmarshal([]byte(mes.Data), &loginResMes)
	if err != nil {
		fmt.Println("返回消息二次解包异常！:", err)
		return
	}
	if loginResMes.Code == 200 {
		fmt.Println("登录成功")
	} else if loginResMes.Code == 500 {
		fmt.Println(loginResMes.Error)
		fmt.Println("登录失败  用户没有注册！")
	}
	return
}
